/**
 * 
 */
package com.hexacta.hrs.web.struts.actions;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.validation.SkipValidation;

import com.hexacta.hrs.services.report.ReportService;
import com.hexacta.hrs.spring.PersonRetriever;
import com.hexacta.hrs.web.struts.actions.security.PermissionChecker;
import com.opensymphony.xwork2.ActionSupport;

/**
 * @author mfunes
 * 
 */
public abstract class BaseReportAction extends ActionSupport implements ServletResponseAware, ServletRequestAware {

    private static final long serialVersionUID = 8221777951670184696L;

    private String actionMethod;

    private String reportName;

    private ReportService reportService;

    private InputStream reportStream;

    private HttpServletResponse servletResponse;

    private PersonRetriever personRetriever;

    private PermissionChecker permissionChecker = new PermissionChecker();

    protected HttpServletRequest request;

    @Override
    public void setServletRequest(final HttpServletRequest request) {
        this.request = request;
    }

    public PersonRetriever getPersonRetriever() {
        return personRetriever;
    }

    public void setPersonRetriever(final PersonRetriever personRetriever) {
        this.personRetriever = personRetriever;
    }

    public InputStream getReportStream() {
        return reportStream;
    }

    public void setReportStream(final InputStream reportStream) {
        this.reportStream = reportStream;
    }

    public HttpServletResponse getServletResponse() {
        return servletResponse;
    }

    public String getReportName() {
        return reportName;
    }

    public void setReportName(final String reportName) {
        this.reportName = reportName;
    }

    public ReportService getReportService() {
        return reportService;
    }

    public void setReportService(final ReportService reportService) {
        this.reportService = reportService;
    }

    public String getActionMethod() {
        return actionMethod;
    }

    public String getDestination() {
        return getActionMethod();
    }

    public void setActionMethod(final String actionMethod) {
        this.actionMethod = actionMethod;
    }

    @SkipValidation
    public final String exportToPDF() {
        ByteArrayOutputStream reportResponseStream;
        Map<String, Object> filters = getReportFilters();
        try {
            reportResponseStream = reportService.createPDFReport(reportName, filters, getReportParameters());
            // servletResponse.setHeader("Content-Disposition",
            // "attachment; filename=" + reportName.replace(' ', '_')
            // + ".pdf");
            servletResponse.setHeader("Expires", "0");
            servletResponse.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            servletResponse.setHeader("Pragma", "public");
            servletResponse.getOutputStream().write(reportResponseStream.toByteArray());
            ByteArrayInputStream bis = new ByteArrayInputStream(reportResponseStream.toByteArray());
            reportStream = bis;

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (RuntimeException ex) {
            addFieldError("pdfReport", ex.getMessage());
            return "success";
        }
        return "pdf";
    }

    /**
     * Devuelve true si el usuario tiene el permiso pasado por parametro, false
     * en otro caso.
     * 
     * @param permission
     * @return
     */
    public boolean hasPermission(final String permission) {
        return getPermissionChecker().hasPermission(permission, request.getSession());
    }

    public void setPermissionChecker(final PermissionChecker permissionChecker) {
        this.permissionChecker = permissionChecker;
    }

    public PermissionChecker getPermissionChecker() {
        return permissionChecker;
    }

    @SkipValidation
    public final String exportToExcel() {
        ByteArrayOutputStream reportResponseStream;
        try {
            reportResponseStream = reportService.createXLSReport(reportName, getReportFilters(), getReportParameters());
            servletResponse.setHeader("Content-Disposition", "attachment; filename=" + reportName.replace(' ', '_')
                    + ".xls");
            servletResponse.setHeader("Expires", "0");
            servletResponse.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            servletResponse.setHeader("Pragma", "public");
            servletResponse.getOutputStream().write(reportResponseStream.toByteArray());
            ByteArrayInputStream bis = new ByteArrayInputStream(reportResponseStream.toByteArray());
            reportStream = bis;

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (RuntimeException ex) {
            addFieldError("xlsReport", ex.getMessage());
            return "success";
        }
        return "excel";
    }

    /**
     * Overridear si los reportes necesitan filtros.
     * 
     * @return Un Map con los diferentes filtros.
     */
    protected Map<String, Object> getReportFilters() {
        return null;
    }

    public void setServletResponse(final HttpServletResponse response) {
        servletResponse = response;
    }

    /**
     * Lugar donde se escriben los filtros basicos para todos lso reportes.
     * 
     * @return Un Map con los diferentes parametros bases para todos los
     *         reportes.
     */
    @SuppressWarnings("unchecked")
    private Map<String, Object> getReportParameters() {
        Map parameters = new HashMap<String, Object>();
        parameters.put("UserLogged", personRetriever.getLoggedInPerson().getFullName());
        parameters.put("Logo",
                BaseReportAction.class.getClassLoader().getResource("com/hexacta/hrs/images/LogoHexacta.jpg"));
        return parameters;
    }
}